# Advanced Typings

Sometimes you will want to declare the field types separately or use the result type of a query in another function, this can be sone in genql importing some additional types

## The query fields type `QueryRequest`

To declare the fields object separately from the client invocation you can use the `QueryRequest`, `MutationRequest` and `SubscriptionRequest` types

```tsx
import { createClient, QueryRequest } from './generated'

const client = createClient()

// these query fields are validated by typescript and have auto completion
const fields: QueryRequest = {
    countries: {
        name: true,
        code: true,
    },
}

const result = await client.query(fields)
```

## The query result type `QueryResult`

If you want to reuse the result type of a query in another function you can use the `QueryResult`, `MutationResult` and `SubscriptionResult` generic types.
These types take a query object as argument and give the associated result type as result.

> You need to use the `tuple` function to tell typescript to use tuple semantics

```tsx
import { QueryResult } from './generated'

function tuple<T1, T2>(data: [T1, T2]): typeof data
function tuple(data: Array<any>) {
    return data
}

const fields = {
    countries: tuple([
        { argument: 'exampleArgument' },
        {
            name: 1,
            code: 1,
        },
    ]), // tell typescript this is a tuple and not an array
}

// you can use this type in other places
type ReturnedType = QueryResult<typeof fields>

const result: ReturnedType = await client.query(fields)

function takesResultAsArgument(arg: QueryResult<typeof fields>) {
    // do something with the result
}

takesResultAsArgument(result)
```

> Notice that when using `QueryResult` you cannot use the `QueryRequest` type on the fields object because you would lose the selected fields type
